package com.example.maze;

import java.util.ArrayList;
import java.util.Stack;
import android.util.Log;
import android.os.Parcel;
import android.os.Parcelable;

class DataSetObj implements Parcelable {
 //[ ---------- basic filds ----------
   ////[ logic
   int               MAZE_M, 
                     MAZE_N, 
                     CELL_SIZE;   
   Vertex[][]        VERTEXES;      
   ArrayList<Edge>   GRAPH; 
   ArrayList<Edge>   SPANNING_TREE;
   ////[ graphics
   Cell[][]          MAZE_CELLS;   
   //] ---------- basic filds ----------
   
   int myPosM, 
       myPosN;         
   int visualRangeM, 
       visualRangeN; 
   int fromM, 
       fromN, 
       toM, 
       toN;
   int midM, 
       midN; 
   Stack<Flag> flags; 
   
   public DataSetObj() {}
   //[ readObj
   public DataSetObj(Parcel in) {
      
   }
   
   @Override
   public int describeContents() {
      return 0;
   }
   /*
   private final void savedMazeDimInfo(Parcel dest) {
      dest.writeInt(MAZE_M);
      dest.writeInt(MAZE_N);
      dest.writeInt(CELL_SIZE);
   }
   private final void savedDataStructrueInfo(Parcel dest) {
      dest.writeArray(VERTEXES);
      //dest.writeTypedList(GRAPH);
   }
   */
   //[ writeObj
   @Override
   public void writeToParcel(Parcel dest, int flags) {
      //savedMazeDimInfo(dest);
      //savedDataStructrueInfo(dest);
      // do nothing
   }
   
   public static final Parcelable.Creator<DataSetObj> CREATOR=
      new Parcelable.Creator<DataSetObj>() {
         @Override
         public DataSetObj createFromParcel(Parcel in) {
            return new DataSetObj(in);
         }
         @Override
         public DataSetObj[] newArray(int size) {
            return new DataSetObj[size];
         }
   };
}

class DataSet {
   static GamePanel GAME_PANEL;            
   
   //[ ---------- basic filds ----------
   ////[ logic
   static int               MAZE_M, 
                            MAZE_N, 
                            CELL_SIZE;  
   static long[]            ST_EDGES;
   static Vertex[][]        VERTEXES;      
   static ArrayList<Edge>   GRAPH; 
   static ArrayList<Edge>   SPANNING_TREE;
   ////[ graphics
   static Cell[][]          MAZE_CELLS;   
   //] ---------- basic filds ----------
   
   //[ 玩家位置
   static int myPosM=0, myPosN=0;         
   //[ 限制畫面上可視格數, visualRangeM(縱)visualRangeN(橫)
   static int visualRangeM=19, visualRangeN= 9; 
   //[ (fromM, fromN)到 (toM, toN) 為實際可視範圍
   static int fromM= 0, fromN= 0, toM= fromM+visualRangeM, toN= fromN+visualRangeN;
   //[ 當走到 midM或 midN時, (fromM, fromN)和(toM, toN)開始隨著變化
//   static int midM= visualRangeM/2+fromM, midN= visualRangeN/2+fromN; 
   //[ flag(旗標)的堆疊
   static Stack<Flag> flags= new Stack<Flag>(); 
   //[ 系統列
   static int sysBarHeight;
   //[ 螢幕的寬高(不含系統列)
   static int screenWidth, screenHeight;
   
   //[ ---------- listener part ----------
   private static MazeContentListenerI mMazeContentListener; 
   private static GameFinishedListenerI mGameFinishedListener;
   private static RadarManagerListenerI mShowRadarListener;
   ////[ 有關 Maze內容
   public static void addMCListener(MazeContentListenerI listener) {
      mMazeContentListener= listener;
   }
   public static void positionChanged() {
      mMazeContentListener.positionChanged();
   }
   public static void markChanged() {
      mMazeContentListener.positionChanged();
   }
   ////[ 遊戲終了
   public static void addListener(GameFinishedListenerI listener) {
      mGameFinishedListener= listener;
   }
   public static void reachExit() {
      mGameFinishedListener.reachExit();
   }
   public static void timeOut() {
      mGameFinishedListener.timeOut();
   }   
   ////[ show 雷達圖
   public static void addSRListener(RadarManagerListenerI listener) {
      mShowRadarListener= listener;
   }
   public static void showRadar() {
      mShowRadarListener.showRadar();
   }
   public static void hideRadar() {
      mShowRadarListener.hideRadar();
   }
   //] ---------- listener part ----------        
   
   // --------------------------------------------------
   public static void initCellState() {
      for(int i=0; i<MAZE_M; i++) {
         for(int j=0; j<MAZE_N; j++) {
            MAZE_CELLS[i][j].type = Cell.NORMAL;
            MAZE_CELLS[i][j].state= Cell.NON_FOCUS;
            MAZE_CELLS[i][j].mark = Cell.NO;
            MAZE_CELLS[i][j].flag = Cell.NO;
            MAZE_CELLS[i][j].trace= Cell.NO;
//            MAZE_CELLS[i][j].robotFootmark= Cell.NO_VISIT; //>>>>還會用到嗎?
//            MAZE_CELLS[i][j].isVisited    = false;         //>>>>還會用到嗎?
         }
      }
      MAZE_CELLS[0][0].type= Cell.ENTRY;
      MAZE_CELLS[MAZE_M-1][MAZE_N-1].type= Cell.EXIT;
   }
   // --------------------------------------------------   
   public static void initFlagsState() {
      flags.clear();
      Flag.NUM_OF_FLAG=0;
   }
   // --------------------------------------------------   
   public static void initPosition() {
      myPosM=0; myPosN=0;
   }
   // --------------------------------------------------   
   private static void resetVisualRange() {
      fromM= myPosM-DataSet.visualRangeM/2; 
      fromN= myPosN-DataSet.visualRangeN/2;
      toM  = fromM+(DataSet.visualRangeM-1); // because 0..M-1
      toN  = fromN+(DataSet.visualRangeN-1); // because 0..N-1
    
       if(fromM<0) {
         fromM= 0;
         toM  = fromM+(DataSet.visualRangeM-1); 
      } else if(toM>=DataSet.MAZE_M) {
         toM  = DataSet.MAZE_M-1;
         fromM= toM-(DataSet.visualRangeM-1);                  
      }
    
      if(fromN<0) {
         fromN= 0;
         toN  = fromN+(DataSet.visualRangeN-1);
      } else if(toN>=DataSet.MAZE_N) {
         toN  = DataSet.MAZE_N-1;
         fromN= toN-(DataSet.visualRangeN-1);
      }
   }
   public static void resetMyPosition(int pm, int pn) {
      myPosM= pm;
      myPosN= pn;
      resetVisualRange();    
      
      //[ I arrive!
      if(myPosM==MAZE_M-1 && myPosN==MAZE_N-1) {
         reachExit();
      }         
   }
   // --------------------------------------------------
   public static void setVisualMNSize(int m, int n) {
      visualRangeM= m;
      visualRangeN= n;
   }

 //[ ---------- info methods ----------
   public static void mazeInfo() {
      Log.d("mazeInfo", "*** MAZE INFO ****");
      Log.d("mazeInfo", "M        : "+MAZE_M);
      Log.d("mazeInfo", "N        : "+MAZE_N);
      Log.d("mazeInfo", "Cell size: "+CELL_SIZE);
      Log.d("mazeInfo", "*** MAZE INFO ****");
   }
   public static void vertexesInfo() {
      System.out.print("*** VERTEXES INFO ****");
      for(int i=0; i<MAZE_M; i++) {
         for(int j=0; j<MAZE_N; j++) {
            if(j%3 == 0) System.out.println("");            
            System.out.print(VERTEXES[i][j]); 
            System.out.print(",\t");
         }    
      } 
      System.out.println("\n*** VERTEXES INFO ****"); 
   }
   public static void graphInfo() {
      System.out.print("*** GRAPH INFO ****");
      for(int i=0; i<GRAPH.size(); i++) {
         if(i%3 == 0) System.out.println(""); 
         System.out.print(i);             // The index of edge in the list.
         System.out.print(GRAPH.get(i)); 
         System.out.print(",\t"); 
      } 
      System.out.println("\n*** GRAPH INFO ****"); 
   }
   public static void spanningTreeInfo() {
      System.out.print("*** Spanning Tree INFO ****");
      for(int i=0; i<SPANNING_TREE.size(); i++) {
         if(i%3 == 0) System.out.println(""); 
         System.out.print(i);             // The index of edge in the list.
         System.out.print(SPANNING_TREE.get(i)); 
         System.out.print(",\t"); 
      } 
      System.out.println("\n*** Spanning Tree INFO ****"); 
   }
   //[ ---------- info methods ----------
   
   //[ >>>>還會用到嗎?
   public static void initVsState() {
      for(int i=0; i<MAZE_M; i++) {
         for(int j=0; j<MAZE_N; j++) {
            VERTEXES[i][j].visit= false;
         }
      }
   }
   //]

}